/**
 * +======================================================================================================================+
 * @Author: CimZzz
 * @Date: 2023-03-08 14:41:58
 * 
 * 代码分割块，以下内容涉及: 
 * 
 * 针对文件的测试用例, 包括以下功能测试
 * 
 * 1. 通过相对路径获取文件绝对路径
 * 2. 通过绝对路径获取文件路径
 * 3. 判断文件存在与不存在
 * 4. 生成文件夹测试
 * 5. 删除文件夹测试
 * 6. 生成文件测试
 * 7. 删除文件测试
 * 8. 文件类型检查
 * 9. 嵌套创建文件夹
 */
#include "vl_file.h"

using namespace VL;

std::shared_ptr<File> checkAndGetFile(const std::shared_ptr<File>& dir, const std::string& name, const std::string& realName = "") {
	char fileSeperator = File::getFileSeperator();
	std::string afterPath = dir->getAbsolutePathStr();
	afterPath += fileSeperator;
	afterPath += realName != "" ? realName : name;
	auto filePtr = std::make_shared<File>(dir.get(), name);
	if(afterPath != filePtr->getAbsolutePath()) {
		printf("path not equal: %s != %s\n", afterPath.c_str(), filePtr->getAbsolutePathStr());
		exit(1);
	}
	return filePtr;
}

std::shared_ptr<File> checkAndGetFile(const std::string& dir, const std::string& name) {
	char fileSeperator = File::getFileSeperator();
	std::string afterPath = dir;
	afterPath += fileSeperator;
	afterPath += name;
	auto filePtr = std::make_shared<File>(dir, name);
	if(afterPath != filePtr->getAbsolutePath()) {
		printf("path not equal: %s != %s\n", afterPath.c_str(), filePtr->getAbsolutePathStr());
		exit(1);
	}
	return filePtr;
}

void checkExist(const std::shared_ptr<File>& dir) {
	if(!dir->isExist()) {
		exit(2);
	}
}

void checkIsDir(const std::shared_ptr<File>& dir) {
	if(dir->getFileType() != FileType::Directory) {
		exit(3);
	}
}

void checkMkdir(const std::shared_ptr<File>& dir) {
	if(!dir->mkdir()) {
		exit(4);
	}
}

void checkTouch(const std::shared_ptr<File>& file) {
	if(!file->touch()) {
		exit(5);
	}
}

void checkNotExist(const std::shared_ptr<File>& file) {
	if(file->isExist()) {
		exit(6);
	}
}

void checkRemove(const std::shared_ptr<File>& file) {
	if(!file->remove()) {
		exit(7);
	}
}

void checkIsFile(const std::shared_ptr<File>& file) {
	if(file->getFileType() != FileType::File) {
		exit(8);
	}
}

void checkMkdirs(const std::shared_ptr<File>& dir) {
	if(!dir->mkdirs()) {
		exit(9);
	}
}

void checkRename(const std::shared_ptr<File>& dir, const std::shared_ptr<File>& dir2) {
	if(!dir->rename(dir2.get())) {
		exit(10);
	}
}

void checkCopy(const std::shared_ptr<File>& dir, const std::shared_ptr<File>& dir2) {
	if(!dir->copy(dir2.get())) {
		exit(11);
	}
}

void checkRelative(const std::shared_ptr<File>& dir, const std::shared_ptr<File>& dir2, const std::string& equal) {
	if(dir->relativeTo(dir2.get()) != equal) {
		printf("%s != %s\n", dir->relativeTo(dir2.get()).c_str(), equal.c_str());
		exit(12);
	}
}

int main(int argc, char ** argv) {
	if(argc < 1) {
		printf("must have one argument!\n");
		return 1;
	}
	std::string projectPath(argv[1]);
	
	auto vl_buildDir = checkAndGetFile(projectPath, ".vl_build");
	// .vl_build 文件夹一定存在
	checkExist(vl_buildDir);
	checkIsDir(vl_buildDir);

	auto testDir = checkAndGetFile(vl_buildDir, ".pass_test");
	if(testDir->isExist()) {
		checkRemove(testDir);
	}
	checkMkdir(testDir);

	auto testFile = checkAndGetFile(testDir, "test_file");
	checkTouch(testFile);
	checkRemove(testFile);
	checkNotExist(testFile);
	checkTouch(testFile);
	checkExist(testFile);
	checkRemove(testDir);
	checkNotExist(testDir);
	checkNotExist(testFile);

	// 嵌套创建文件夹
	checkMkdirs(testFile);
	checkIsDir(testDir);
	checkIsDir(testFile);

	auto testFile2 = checkAndGetFile(testDir, "test_file2");
	checkRename(testFile, testFile2);
	checkNotExist(testFile);
	checkIsDir(testFile2);

	auto testFile3 = checkAndGetFile(testDir, "test_file3");
	std::ofstream output(testFile3->getAbsolutePath());
	output << "123";
	output.close();
	checkTouch(testFile3);
	checkCopy(testFile3, testFile);
	checkIsFile(testFile);
	checkIsFile(testFile3);
	checkRelative(testFile3, vl_buildDir, ".vl_build/.pass_test/test_file3");
	return 0;
}